package com.wsx.ones.user;

import com.google.gson.Gson;
import com.wsx.ones.core.redis.RedisClientTemplate;
import com.wsx.ones.core.secure.CryptoUtil;
import com.wsx.ones.ehcache.UserEhcacheManager;
import com.wsx.ones.finalstr.common.CommonFinalUtil;
import com.wsx.ones.finalstr.common.RedisFinalUtil;
import com.wsx.ones.finalstr.common.UserTokenUtil;
import com.wsx.ones.user.settings.SettingsBaseParam;
import com.wsx.ones.web.controller.BaseController;
import com.wsx.ones.web.controller.WebController;
import com.wsx.ones.web.model.BaseUser;
import com.wsx.ones.web.model.OutputData;
import com.wsx.ones.web.util.PojoCopy;
import com.wsx.ones.web.vo.BaseVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/User")
public abstract class UserBaseController extends BaseController implements WebController {

	@Autowired
	private RedisClientTemplate redisClientTemplate;

	/**
	 * 校验数据的必须参数设置
	 * @param userParam
	 * @return
	 */
	protected boolean checkSignupParam(UserParam userParam) {
		if (null == userParam) {
			return false;
		}
		if (StringUtils.isEmpty(userParam.getPhone())) {
			return false;
		}
		if (StringUtils.isEmpty(userParam.getUtype())) {
			return false;
		}
		if (StringUtils.isEmpty(userParam.getPasswd())) {
			return false;
		}
		return true;
	}

	/**
	 * 解密加密处理
	 * 解密针对客户端传递的数据
	 * 加密针对数据存储
	 * @param userParam
	 */
	protected void reconPasswd(UserParam userParam) {
		String origpsd = CryptoUtil.decrypt(userParam.getPasswd());
		userParam.setPasswd(CryptoUtil.encrypt(origpsd));
	}

	@Override
	public BaseUser setUserCache(BaseUser baseUser, boolean ifEhcache) {
		return this.setUserCache(baseUser, ifEhcache, UserLoginEnum.NONE);
	}
	public BaseUser setUserCache(BaseUser baseUser, boolean ifEhcache, UserLoginEnum loginEnum) {
		if (ifEhcache) {
			UserEhcacheManager.getInstance().setBaseUser(baseUser);
		}
		Gson gson = new Gson();
		String userJson = gson.toJson(baseUser);
		redisClientTemplate.set(String.valueOf(baseUser.getUid()), userJson, RedisFinalUtil.DB_USER_INFO);
		//
		switch (loginEnum) {
			case LNAME:
				redisClientTemplate.set(baseUser.getLname(), userJson, RedisFinalUtil.DB_USER_INFO);
				break;
			case PHONE:
				redisClientTemplate.set(baseUser.getPhone(), userJson, RedisFinalUtil.DB_USER_INFO);
				break;
			case EMAIL:
				redisClientTemplate.set(baseUser.getEmail(), userJson, RedisFinalUtil.DB_USER_INFO);
				break;
			default:
				break;
		}
		return baseUser;
	}


	public BaseUser getUserCache(String key, boolean isEhcache) {
		BaseUser baseUser = null;
		if (isEhcache) {
			baseUser = UserEhcacheManager.getInstance().getLoginUser(key);
		}
		if (null == baseUser) {
			String result = redisClientTemplate.get(key, RedisFinalUtil.DB_USER_INFO);
			Gson gson = new Gson();
			baseUser = gson.fromJson(result, BaseUser.class);
		}

		return baseUser;
	}


	/**
	 * 验证用户是否已经存在，该方法设计的初衷是不要洞穿db层，redis层就直接返回
	 * 所以设计的前提是redis是高可用的，前期设计是洞穿db的，后期再删减
	 * @param userParam
	 * @return
	 */
	protected boolean checkExistUser(UserParam userParam, UserLoginEnum userLoginEnum) {
		String key = CommonFinalUtil.STRING_EMPTY;

		switch (userLoginEnum) {
			case PHONE:
				key = userParam.getPhone();
				break;
			case LNAME:
				key = userParam.getLname();
				break;
			case EMAIL:
				key = userParam.getEmail();
				break;
			default:
				break;
		}

		if (StringUtils.isEmpty(key)) {
			return true;
		}

		BaseUser baseUser = getUserCache(key, false);
		if (null != baseUser && !StringUtils.isEmpty(baseUser.getUid())) {
			return true;
		}

		return false;
	}

	/**
	 * 生成客户端缓存
	 * @param userBaseVo
	 * @param response
	 */
	protected void setUserTokenCookie(UserBaseVo userBaseVo, HttpServletResponse response) {
		Cookie cookie = new Cookie(UserTokenUtil.COOKIE_USER_TOKEN, userBaseVo.getToken());
		cookie.setMaxAge(UserTokenUtil.COOKIE_USER_AGE);
		cookie.setPath(UserTokenUtil.COOKIE_USER_PATH);
		cookie.setDomain(UserTokenUtil.COOKIE_USER_DOMAIN);
		response.addCookie(cookie);
	}

	/**
	 *验证用户的必填内容，保证数据唯一的内容
	 * @param userParam
	 * @param userLoginEnum
	 * @return
	 */
	protected boolean checkUserParam(UserParam userParam, UserLoginEnum userLoginEnum) {
		switch (userLoginEnum) {
			case LNAME:
				if (StringUtils.isEmpty(userParam.getLname())) {
					return false;
				}
				break;
			case PHONE:
				if (StringUtils.isEmpty(userParam.getPhone())) {
					return false;
				}
				break;
			case EMAIL:
				if (StringUtils.isEmpty(userParam.getEmail())) {
					return false;
				}
				break;
			default:
				break;
		}

		return true;
	}

	protected boolean checkLoginParam(UserParam userParam, UserLoginEnum userLoginEnum) {
		switch (userLoginEnum) {
			case PHONE:
				if (StringUtils.isEmpty(userParam.getPhone())) {
					return false;
				}
				break;
			case EMAIL:
				if (StringUtils.isEmpty(userParam.getEmail())) {
					return false;
				}
				break;
			default:
				break;
		}
		if (StringUtils.isEmpty(userParam.getPasswd())) {
			return false;
		}

		return true;
	}

	/**
	 * 执行用户更新时的必填参数验证
	 * @param baseParam
	 * @return
	 */
	public boolean checkUpdateUser(SettingsBaseParam baseParam) {

		return true;
	}

	@Override
	public OutputData checkVo(BaseVo vo, Class<? extends OutputData> clazz) {
		switch (vo.getReturnStatus()) {
			case SUCCESS:

				break;
			case ERROR_SQL:
			case ERROR_UNKNOW:
				return new OutputData(WebController.CODE_ERROR_SERVER, WebController.STATUS_ERROR_UNKNOWN);
			case DATA_EXIST:
				return new OutputData(WebController.CODE_ERROR_SERVER, WebController.STATUS_DATA_EXIT);
			default:
				break;
		}
		return PojoCopy.copy(vo, clazz);
	}

	public OutputData checkVo(BaseVo vo, Class<? extends OutputData> clazz, HttpServletResponse response) {
		switch (vo.getReturnStatus()) {
			case SUCCESS:
				doSuccessVo(vo, response);
				break;
			case ERROR_SQL:
			case ERROR_UNKNOW:
				return new OutputData(WebController.CODE_ERROR_SERVER, WebController.STATUS_ERROR_UNKNOWN);
			case DATA_EXIST:
				return new OutputData(WebController.CODE_ERROR_SERVER, WebController.STATUS_DATA_EXIT);
			default:
				break;
		}
		return PojoCopy.copy(vo, clazz);
	}
}
